<?php declare(strict_types=1);

namespace App\Services\Refund;

use App\Common\RefundSuccessAction;
use App\Exceptions\BizException;
use App\Models\MerchantWalletDetail;
use App\Models\Order;
use App\Models\RefundOrder;
use App\Models\RefundOrderDoing;
use App\Models\UserWalletDetail;
use App\Services\Refund\Strategy\CibRefundStrategy;
use App\Services\Refund\Strategy\GtxyRefundStrategy;
use App\Services\Refund\Strategy\LeshuaunionRefundStrategy;
use App\Services\Refund\Strategy\VbillRefundStrategy;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

class RefundService
{

    public $company = [];

    public function __construct()
    {
        $str = env("REFUND_QUERY_COMPANY");
        $strArr = explode(",", $str);
        $this->company = $strArr;
    }

    public function isRefundQuery(string $company): bool
    {
        if (in_array($company, $this->company)) {
            return true;
        }
        return false;
    }

    public function refundQuery(RefundOrderDoing $doing,array $data): array
    {
        try {
            $validator = Validator::make($data, [
                "refund_no" => ["required"],
            ]);
            if ($validator->fails()) {
                throw new BizException($validator->errors()->first());
            }
            $order = Order::query()->where("out_trade_no", $doing->out_trade_no)->first();
//            退款中涉及通道【兴业，随行付，国通，乐刷】
            switch ($order->company) {
                case "leshuaunion":
                    $result = (new LeshuaunionRefundStrategy())->refundQuery([
                        "refund_no" => $doing->refund_no,
                        "out_trade_no" => $order->out_trade_no,
                        "store_id" => $order->store_id
                    ]);
                    break;
                case "cib":
                    $result = (new CibRefundStrategy())->refundQuery([
                        "store_id" => $order->store_id,
                        "out_trade_no" => $order->out_trade_no,
                        "refund_no" => $doing->refund_no,
                    ]);
                    break;
                case "vbill":
                    $result = (new VbillRefundStrategy())->refundQuery([
                        "store_id" => $order->store_id,
                        "refund_no" => $doing->refund_no
                    ]);
                    break;
                case "gtxy":
                case "gtxy_v2":
                    $result = (new GtxyRefundStrategy())->refundQuery([
                        "refund_no" => $doing->refund_no,
                        "company" => $order->company,
                        "store_id" => $order->store_id
                    ]);
                    break;
                default:
                    throw new BizException("暂不支持");
            }

            if (empty($result)) {
                throw new BizException("暂不支持");
            }
            $refund_status = 0;
            $refund_no = $out_trade_no = $other_refund_no = $refund_detail = $refund_time = "";
            if ($result["status"] == 1) {
                $refund_status = 1;
                $other_refund_no = $result["other_refund_no"];
                $refund_detail = $result["refund_detail"];
                $refund_time = $result["refund_time"];
            } else if ($result["status"] == 0) {
                $refund_status = 0;
            } else if ($result["status"] == -1) {
                $refund_status = 0;
            }

            $response = [
                "refund_status" => $refund_status,
                "refund_no" => $refund_no,
                "out_trade_no" => $out_trade_no,
                "other_refund_no" => $other_refund_no,
                "refund_detail" => $refund_detail,
                "refund_time" => $refund_time
            ];
            $new_refund_amount = $order->refund_amount + $doing->refund_amount; //总退款
            $new_fee_amount = round(($order->total_amount - $new_refund_amount) * ($order->rate / 100), 2); //退款后的手续费
            switch ($refund_status) {
                case 1:
                    $insert_data = [
                        'status' => '6',
                        'pay_status' => 6,
                        'pay_status_desc' => '已退款',
                        'refund_amount' => $new_refund_amount,
                        'fee_amount' => $new_fee_amount
                    ];
                    if ($order->ways_source == 'weixin' && !empty($refund_detail)) {
                        \App\Common\PaySuccessAction::addCoupon($order->out_trade_no, $refund_detail, 'refund');
                    }
                    (new \App\Api\Controllers\BaseController())->update_day_order($insert_data, $order->out_trade_no);
                    RefundOrder::create([
                        'ways_source' => $order->ways_source,
                        'type' => $order->ways_type,
                        'refund_amount' => $doing->refund_amount, //退款金额
                        'refund_no' => $doing->refund_no, //平台退款单号
                        'store_id' => $order->store_id,
                        'merchant_id' => $order->merchant_id,
                        'out_trade_no' => $order->out_trade_no,
                        'trade_no' => $order->trade_no,
                        "other_refund_no" => $other_refund_no
                    ]);
                    RefundOrderDoing::query()->where(["refund_no" => $data["refund_no"]])->update(["status" => 2]);
                    //退款成功后的操作
                    RefundSuccessAction::action([
                        'out_trade_no' => $order->out_trade_no,
                        'refund_no' => $doing->refund_no, //平台退款单号
                    ]);
                    //返佣去掉
                    UserWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                        'settlement' => '03',
                        'settlement_desc' => '退款订单'
                    ]);
                    MerchantWalletDetail::where('out_trade_no', $order->out_trade_no)->update([
                        'settlement' => '03',
                        'settlement_desc' => '退款订单'
                    ]);
                    break;
                case 0:
                    $insert_data = [
                        'status' => '5',
                        'pay_status' => 5,
                        'pay_status_desc' => '退款中'
                    ];
                    $res = (new \App\Api\Controllers\BaseController())->update_day_order($insert_data, $data['out_trade_no']);
                    if (!$res) {
                        Log::info('乐刷-退款中-更新失败');
                    }
                    RefundOrderDoing::query()->where(["refund_no" => $data["refund_no"]])->update(["status" => 1]);
                    break;
                case -1:
                    RefundOrderDoing::query()->where(["refund_no" => $data["refund_no"]])->update(["status" => -1]);
                    break;
            }
            return [
                "status" => 1,
                "message" => "查询成功",
                "data" => $response
            ];
        } catch (\Exception $e) {
            return [
                "status" => -1,
                "message" => $e->getMessage()
            ];
        }
    }

}